home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / JFC.bin / ListView.java < prev    next >
Text File  |  1998-06-30  |  12KB  |  381 lines

  1. /*
  2.  * @(#)ListView.java    1.13 98/03/13
  3.  * 
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  */
  20. package com.sun.java.swing.text.html;
  21.  
  22. import java.util.Enumeration;
  23. import java.awt.*;
  24. import java.net.URL;
  25. import java.util.StringTokenizer;
  26. import java.net.MalformedURLException;
  27. import com.sun.java.swing.Icon;
  28. import com.sun.java.swing.ImageIcon;
  29. import com.sun.java.swing.border.*;
  30. import com.sun.java.swing.text.*;
  31.  
  32. /**
  33.  * A view implementation to display an html list
  34.  *
  35.  * @author  Timothy Prinzing
  36.  * @author  Sara Swanson
  37.  * @version 1.13 03/13/98
  38.  */
  39. class ListView extends HTMLBoxView  {
  40.  
  41.     private String type = null;
  42.     private int start = 1;
  43.     URL imageurl;
  44.     Icon img = null;
  45.     private int bulletgap = 5;
  46.  
  47.     /**
  48.      * Creates a new view that represents a list element.
  49.      *
  50.      * @param elem the element to create a view for
  51.      */
  52.     public ListView(Element elem) {
  53.     super(elem, View.Y_AXIS);
  54.     setParagraphInsets(elem.getAttributes());
  55.     AttributeSet attr = elem.getAttributes();
  56.  
  57.     if (attr != null) {
  58.         String bgstr = (String)attr.getAttribute("-bullet-gap");
  59.         if (bgstr != null) {
  60.         try {
  61.                 bulletgap = (Integer.valueOf(bgstr)).intValue();
  62.         } catch (NumberFormatException e) {
  63.             bulletgap = 5;
  64.         }
  65.         }
  66.  
  67.         /* Get the image to use as a list bullet */
  68.         String imgstr = (String)attr.getAttribute("list-style-image");
  69.         if (imgstr == null) {
  70.             imgstr = (String)attr.getAttribute("list-style");
  71.         }
  72.         if (imgstr == null) {
  73.         type = null;
  74.         } else if (imgstr.equalsIgnoreCase("none")) {
  75.         type = new String("none");
  76.         } else {
  77.                 try {
  78.             String tmpstr = null;
  79.             StringTokenizer st = new StringTokenizer(imgstr, "()");
  80.             if (st.hasMoreTokens())
  81.             tmpstr = st.nextToken();
  82.             if (st.hasMoreTokens())
  83.             tmpstr = st.nextToken();
  84.                     URL u = new URL(tmpstr);
  85.                     img = new ImageIcon(u);
  86.             type = new String("html-image");
  87.                 } catch (MalformedURLException e) {
  88.             type = null;
  89.                 }
  90.         }
  91.  
  92.         /* Get the type of bullet to use in the list */
  93.         String typestr = (String) attr.getAttribute("type");
  94.         if ((typestr == null) || (typestr == Constants.NULL_ATTRIBUTE)) {
  95.             if (type == null) {
  96.             String nm = elem.getName();
  97.             if ((nm != null) && nm.equalsIgnoreCase("ol")) {
  98.             type = new String("1");
  99.             } else {
  100.                     type = (String) attr.getAttribute("list-style-type");
  101.                     if ((type == null) 
  102.                 || (type == Constants.NULL_ATTRIBUTE)) {
  103.                         type = (String) attr.getAttribute("list-style");
  104.                         if ((type == null) 
  105.                 || (type == Constants.NULL_ATTRIBUTE))
  106.                 type = new String("disc");
  107.                 }
  108.             }
  109.         }
  110.         } else {
  111.         type = typestr;
  112.         }
  113.  
  114.         /* Get the number to start the list with */
  115.         String startstr = (String)attr.getAttribute("start");
  116.         if (startstr != null) {
  117.         try {
  118.                 start = (Integer.valueOf(startstr)).intValue();
  119.         } catch (NumberFormatException e) {
  120.         }
  121.         }
  122.  
  123.     }
  124.     }
  125.  
  126.     /**
  127.      * Calculates the desired shape of the list.
  128.      *
  129.      * @return the desired span
  130.      * @see View#getPreferredSpan
  131.      */
  132.     public float getAlignment(int axis) {
  133.         switch (axis) {
  134.         case View.X_AXIS:
  135.             return 0.5f;
  136.         case View.Y_AXIS:
  137.             return 0.5f;
  138.         default:
  139.             throw new IllegalArgumentException("Invalid axis: " + axis);
  140.         }
  141.     }
  142.  
  143.     /**
  144.      * Paints one of the children; called by paint().  By default
  145.      * that is all it does, but a subclass can use this to paint 
  146.      * things relative to the child.
  147.      *
  148.      * @param g the graphics context
  149.      * @param alloc the allocation region
  150.      * @param index the index of the child
  151.      */
  152.     protected void paintChild(Graphics g, Rectangle alloc, int index) {
  153.     View v = getView(index);
  154.     AttributeSet a = v.getElement().getAttributes();
  155.     String childtype = (String) a.getAttribute("type");
  156.     if (childtype == null) {
  157.         childtype = type;
  158.     }
  159.  
  160.     if (childtype.equalsIgnoreCase("square")) {
  161.             drawShape(g, childtype, alloc.x, alloc.y, alloc.height, 
  162.             v.getAlignment(View.Y_AXIS));
  163.     } else if (childtype.equalsIgnoreCase("circle")) {
  164.             drawShape(g, childtype, alloc.x, alloc.y, alloc.height, 
  165.             v.getAlignment(View.Y_AXIS));
  166.     } else if (childtype.equalsIgnoreCase("1")
  167.         || childtype.equalsIgnoreCase("decimal")) {
  168.         drawLetter(g, '1', alloc.x, alloc.y, alloc.height, index);
  169.     } else if (childtype.equals("a")
  170.         || childtype.equalsIgnoreCase("lower-alpha")) {
  171.         drawLetter(g, 'a', alloc.x, alloc.y, alloc.height, index);
  172.     } else if (childtype.equals("A")
  173.         || childtype.equalsIgnoreCase("upper-alpha")) {
  174.         drawLetter(g, 'A', alloc.x, alloc.y, alloc.height, index);
  175.     } else if (childtype.equals("i")
  176.         || childtype.equalsIgnoreCase("lower-roman")) {
  177.         drawLetter(g, 'i', alloc.x, alloc.y, alloc.height, index);
  178.     } else if (childtype.equals("I")
  179.         || childtype.equalsIgnoreCase("upper-roman")) {
  180.         drawLetter(g, 'I', alloc.x, alloc.y, alloc.height, index);
  181.     } else if (childtype.equalsIgnoreCase("html-image")) {
  182.             drawIcon(g, alloc.x, alloc.y, alloc.height, 
  183.             v.getAlignment(View.Y_AXIS));
  184.     } else if (childtype.equals("none")) {
  185.         ;
  186.     } else {
  187.     //else if (childtype.equalsIgnoreCase("disc"))
  188.             drawShape(g, childtype, alloc.x, alloc.y, alloc.height, 
  189.             v.getAlignment(View.Y_AXIS));
  190.     }
  191.  
  192.     super.paintChild(g, alloc, index);
  193.     }
  194.  
  195.     /**
  196.      * Draws the bullet icon specified by the list-style-image argument.
  197.      *
  198.      * @param g     the graphics context
  199.      * @param ax    x coordinate to place the bullet
  200.      * @param ay    y coordinate to place the bullet
  201.      * @param ah    height of the container the bullet is placed in
  202.      * @param align preferred alignment factor for the child view
  203.      */
  204.     protected void drawIcon(Graphics g, int ax, int ay, int ah,
  205.     float align) {
  206.     g.setColor(Color.black);
  207.     int x = ax - img.getIconWidth() - bulletgap;
  208.     int y = ay + (int)(ah * align) - 3;
  209.  
  210.     img.paintIcon(getContainer(), g, x, y);
  211.     }
  212.  
  213.     /**
  214.      * Draws the graphical bullet item specified by the type argument.
  215.      *
  216.      * @param g     the graphics context
  217.      * @param type  type of bullet to draw (circle, square, disc)
  218.      * @param ax    x coordinate to place the bullet
  219.      * @param ay    y coordinate to place the bullet
  220.      * @param ah    height of the container the bullet is placed in
  221.      * @param align preferred alignment factor for the child view
  222.      */
  223.     protected void drawShape(Graphics g, String type, int ax, int ay, int ah,
  224.     float align) {
  225.     g.setColor(Color.black);
  226.     int x = ax - bulletgap - 7;
  227.     int y = ay + (int)(ah * align) - 3;
  228.  
  229.     if (type.equalsIgnoreCase("square")) {
  230.         g.drawRect(x, y, 7, 7);
  231.     } else if (type.equalsIgnoreCase("circle")) {
  232.         g.drawOval(x, y, 7, 7);
  233.     } else {
  234.     //else if (type.equalsIgnoreCase("disc")) 
  235.         g.fillOval(x, y, 7, 7);
  236.     }
  237.     }
  238.  
  239.     /**
  240.      * Draws the letter or number for an ordered list.
  241.      *
  242.      * @param g     the graphics context
  243.      * @param letter type of ordered list to draw
  244.      * @param ax    x coordinate to place the bullet
  245.      * @param ay    y coordinate to place the bullet
  246.      * @param ah    height of the container the bullet is placed in
  247.      * @param index position of the list item in the list
  248.      */
  249.     protected void drawLetter(Graphics g, char letter, int ax, int ay, int ah,
  250.     int index) {
  251.     g.setColor(Color.black);
  252.     String str = formatItemNum(index + start, letter) + ".";
  253.     FontMetrics fm = g.getFontMetrics();
  254.     int stringwidth = fm.stringWidth(str);
  255.     int x = ax - stringwidth - bulletgap;
  256.     int y = ay + fm.getAscent() + fm.getLeading();
  257.     g.drawString(str, x, y);
  258.     }
  259.  
  260.     /**
  261.      * Converts the item number into the ordered list number
  262.      * (i.e.  1 2 3, i ii iii, a b c, etc.
  263.      *
  264.      * @param itemNum number to format
  265.      * @param type    type of ordered list
  266.      */
  267.     protected String formatItemNum(int itemNum, char type) {
  268.         String numStyle = "1";
  269.  
  270.         boolean uppercase = false;
  271.  
  272.         String formattedNum;
  273.  
  274.         switch (type) {
  275.         case '1':
  276.         default:
  277.             formattedNum = String.valueOf(itemNum);
  278.             break;
  279.  
  280.         case 'A':
  281.             uppercase = true;
  282.             // fall through
  283.         case 'a':
  284.             formattedNum = formatAlphaNumerals(itemNum);
  285.             break;
  286.  
  287.         case 'I':
  288.             uppercase = true;
  289.             // fall through
  290.         case 'i':
  291.             formattedNum = formatRomanNumerals(itemNum);
  292.         }
  293.  
  294.         if (uppercase) {
  295.             formattedNum = formattedNum.toUpperCase();
  296.         }
  297.  
  298.         return formattedNum;
  299.     }
  300.  
  301.     /**
  302.      * Converts the item number into an alphabetic character
  303.      *
  304.      * @param itemNum number to format
  305.      */
  306.     protected String formatAlphaNumerals(int itemNum) {
  307.         String result = "";
  308.  
  309.         if (itemNum > 26) {
  310.             result = formatAlphaNumerals(itemNum / 26) +
  311.                 formatAlphaNumerals(itemNum % 26);
  312.         } else {
  313.             // -1 because item is 1 based.
  314.             result = String.valueOf((char)('a' + itemNum - 1));
  315.         }
  316.  
  317.         return result;
  318.     }
  319.  
  320.     /* list of roman numerals */
  321.     protected static final char romanChars[][] = {
  322.         {'i', 'v'},
  323.         {'x', 'l' },
  324.         {'c', 'd' },
  325.         {'m', '?' },
  326.         };
  327.  
  328.     /**
  329.      * Converts the item number into a roman numeral
  330.      *
  331.      * @param num  number to format
  332.      */
  333.     protected String formatRomanNumerals(int num) {
  334.         return formatRomanNumerals(0, num);
  335.     }
  336.  
  337.     /**
  338.      * Converts the item number into a roman numeral
  339.      *
  340.      * @param num  number to format
  341.      */
  342.     protected String formatRomanNumerals(int level, int num) {
  343.         if (num < 10) {
  344.             return formatRomanDigit(level, num);
  345.         } else {
  346.             return formatRomanNumerals(level + 1, num / 10) +
  347.                 formatRomanDigit(level, num % 10);
  348.         }
  349.     }
  350.  
  351.  
  352.     /**
  353.      * Converts the item number into a roman numeral
  354.      *
  355.      * @param level position
  356.      * @param num   digit to format
  357.      */
  358.     protected String formatRomanDigit(int level, int digit) {
  359.         String result = "";
  360.         if (digit == 9) {
  361.             result = result + romanChars[level][0];
  362.             result = result + romanChars[level + 1][0];
  363.             return result;
  364.         } else if (digit == 4) {
  365.             result = result + romanChars[level][0];
  366.             result = result + romanChars[level][1];
  367.             return result;
  368.         } else if (digit >= 5) {
  369.             result = result + romanChars[level][1];
  370.             digit -= 5;
  371.         }
  372.  
  373.         for (int i = 0; i < digit; i++) {
  374.             result = result + romanChars[level][0];
  375.         }
  376.  
  377.         return result;
  378.     }
  379.  
  380. }
  381.